using System;
using System.Diagnostics;
using System.Globalization;

namespace GeneticAlgorithms.Tools
{
    /// <summary>
    /// Auxiliary class for tracing.
    /// </summary>
    public static class TraceHelper
    {
        /// <summary>
        /// Writes the specified message.
        /// </summary>
        /// <param name="message">The message to be written to trace output.</param>
        public static void Write(string message)
        {
            Write(message, TraceLevel.Info);
        }

        /// <summary>
        /// Writes the specified value.
        /// </summary>
        /// <param name="value">The value to be written to trace output.</param>
        public static void Write(object value)
        {
            string s;
            if (value != null)
            {
                IConvertible c = value as IConvertible;
                if (c != null)
                    s = c.ToString(CultureInfo.InvariantCulture);
                else
                    s = value.ToString();
            }
            else
            {
                s = "(null)";
            }
            Write(s);
        }

        /// <summary>
        /// Writes the specified formated string.
        /// </summary>
        /// <param name="format">The format string.</param>
        /// <param name="args">The addicional arguments to be included.</param>
        public static void Write(string format, params object[] args)
        {
            Write(String.Format(CultureInfo.CurrentCulture, format, args), TraceLevel.Info);
        }

        /// <summary>
        /// Writes the specified message.
        /// </summary>
        /// <param name="message">The message to be written to trace output.</param>
        /// <param name="category">The trace category.</param>
        /// <param name="level">The trace level.</param>
        public static void Write(string message, string category, TraceLevel level)
        {
            if (traceSwitch.Level.CompareTo(level) >= 0)
                Trace.Write(message, category);
        }

        /// <summary>
        /// Writes the specified message.
        /// </summary>
        /// <param name="message">The message to be written to trace output.</param>
        /// <param name="level">The trace level.</param>
        public static void Write(string message, TraceLevel level)
        {
            Write(message, null, level);
        }

        /// <summary>
        /// Writes the message to the trace output, followed by a new line character.
        /// </summary>
        /// <param name="message">The message to be written.</param>
        public static void WriteLine(string message)
        {
            WriteLine(message, TraceLevel.Info);
        }

        /// <summary>
        /// Writes a formatted to the trace output, followed by a new line character.
        /// </summary>
        /// <param name="format">The format string.</param>
        /// <param name="args">The addicional arguments to be included.</param>
        public static void WriteLine(string format, params object[] args)
        {
            WriteLine(String.Format(CultureInfo.CurrentCulture, format, args), TraceLevel.Info);
        }

        /// <summary>
        /// Writes the message to the trace output, followed by a new line character.
        /// </summary>
        /// <param name="message">The message to be written.</param>
        /// <param name="category">The trace category.</param>
        /// <param name="level">The trace level.</param>
        public static void WriteLine(string message, string category, TraceLevel level)
        {
            if (GetTraceSwitch().Level.CompareTo(level) >= 0)
                Trace.WriteLine(message, category);
        }

        /// <summary>
        /// Writes the message to the trace output, followed by a new line character.
        /// </summary>
        /// <param name="message">The message to be written.</param>
        /// <param name="level">The trace level.</param>
        public static void WriteLine(string message, TraceLevel level)
        {
            WriteLine(message, null, level);
        }

        private static TraceSwitch traceSwitch;

        private static TraceSwitch GetTraceSwitch()
        {
            if (traceSwitch == null)
            {
                traceSwitch = new TraceSwitch("level", "Tracing level");
                traceSwitch.Level = TraceLevel.Verbose;
            }

            return traceSwitch;
        }
    }
}
